# vPresent is an immersive presentation creation and display application.
# Copyright (C) 2007-2009 by Priority 5 Holdings, Inc.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

import re, types

import opendocument
import opendocument.core as core
import opendocument.xlink as xlink
od = opendocument
meta_base = opendocument.bases.meta

class Generator(meta_base.Generator):
   __metaclass__ = od.OpenDocumentMeta
   childTypes = ['PlainText']
   def __init__(self, attrs):
      meta_base.Generator.__init__(self, attrs)

class Keyword(meta_base.Keyword):
   __metaclass__ = od.OpenDocumentMeta
   childTypes = ['PlainText']
   def __init__(self, attrs):
      meta_base.Keyword.__init__(self, attrs)

class InitialCreator(meta_base.InitialCreator):
   __metaclass__ = od.OpenDocumentMeta
   childTypes = ['PlainText']
   def __init__(self, attrs):
      meta_base.InitialCreator.__init__(self, attrs)

class PrintedBy(meta_base.PrintedBy):
   __metaclass__ = od.OpenDocumentMeta
   childTypes = ['PlainText']
   def __init__(self, attrs):
      meta_base.PrintedBy.__init__(self, attrs)

class CreationDate(meta_base.CreationDate):
   __metaclass__ = od.OpenDocumentMeta
   childTypes = ['PlainText']
   def __init__(self, attrs):
      meta_base.CreationDate.__init__(self, attrs)

class Template(meta_base.Template):
   def __init__(self, attrs):
      meta_base.Template.__init__(self, attrs)
      self._modificationTime = attrs.get('meta:date', '')
      self._location = xlink.XLink(attrs)

   def getModificationTime(self):
      return self._modificationTime

   def getLocation(self):
      return self._location

class AutoReload(meta_base.AutoReload):
   def __init__(self, attrs):
      meta_base.AutoReload.__init__(self, attrs)
      self._delay    = attrs.get('meta:delay', '')
      print "[TODO] AutoReload: Handle duration", self.delay
      self._location = xlink.XLink(attrs)

   def getLocation(self):
      return self._location

class HyperlinkBehaviour(meta_base.HyperlinkBehaviour):
   SHOW_NEW     = xlink.XLink.SHOW_NEW
   SHOW_REPLACE = xlink.XLink.SHOW_REPLACE

   def __init__(self, attrs):
      meta_base.HyperlinkBehaviour.__init__(self, attrs)
      self._targetFrame = attrs.get('meta:target-frame-name', '')

      if self._targetFrame == '_blank':
         self.setShow('new')
      else:
         self.setShow('replace')

   def getTargetFrame(self):
      return self._targetFrame

   def getShow(self):
      return self._showID

   def setShow(self, show):
      show = show.strip()

      if show == 'new':
         self._show = show
         self._showID = self.SHOW_NEW
#         self.getRawAttributes()['xlink:show'] = show
         if self._targetFrame != '_blank':
            self._targetFrame = '_blank'
#            self.getRawAttributes()['meta:target-frame-name'] = '_blank'
      elif show == 'replace':
         self._show = show
         self._showID = self.SHOW_REPLACE
#         self.getRawAttributes()['xlink:show'] = show

class EditingCycles(meta_base.EditingCycles):
   def __init__(self, attrs):
      meta_base.EditingCycles.__init__(self, attrs)

   def get_cdata(self):
      value = self.__getcdata()
      try:
         value = int(value)
      except ValueError:
         value = 0
      if value < 0:
         value = 0
      return value

   def set_cdata(self, value):
      assert type(value) in [types.IntType,]
      self.__setcdata(str(value))


class EditingDuration(meta_base.EditingDuration):
   def __init__(self, attrs):
      meta_base.EditingDuration.__init__(self, attrs)
      print "[TODO] EditingDuration: Handle duration"

class DocumentStatistic(meta_base.DocumentStatistic):
   __metaclass__ = od.OpenDocumentMeta
   childTypes = ['PlainText']
   #sAttrNameRe = re.compile('([A-Z])')

   def __init__(self, attrs):
      meta_base.DocumentStatistic.__init__(self, attrs)

   # XXX: Fix this. Don't know what it should be doing.
   #def __getattr__(self, name):
   #   if hasattr(self.__dict__, name):
   #      return self.__dict__[name]
   #   else:
   #      # Convert a name such as "attrName" to the form "meta:attr-name" to
   #      # be used as the key for self.attrs.
   #      attr_name = self.sAttrNameRe.sub(r'-\1', name)
   #      key = 'meta:%s' % attr_name.lower()
   #
   #      return self.__dict__['attrs'][key]
   #
   #def __setattr__(self, name, value):
   #   # NOTE: This hack test for 'attrs' is to deal with the fact that we
   #   # need to look at self.attrs in the case when self.__dict__ does not
   #   # have the named attribute. However, when self.attrs is first assigned,
   #   # it will not be in self.__dict__.
   #   if name == 'attrs' or hasattr(self.__dict__, name):
   #      self.__dict__[name] = value
   #   else:
   #      # Convert a name such as "attrName" to the form "meta:attr-name" to
   #      # be used as the key for self.attrs.
   #      attr_name = self.sAttrNameRe.sub(r'-\1', name)
   #      key = 'meta:%s' % attr_name.lower()
   #      self.__dict__['attrs'][key] = value

class PrintDate(meta_base.PrintDate):
   def __init__(self, attrs):
      meta_base.PrintDate.__init__(self, attrs)

class UserDefined(meta_base.UserDefined):
   def __init__(self, attrs):
      meta_base.UserDefined.__init__(self, attrs)

   def get_cdata(self):
      value = self.__getcdata().strip()

      if self.config_type == 'boolean':
         return opendocument.toBoolean(value)
      elif self.config_type == 'short' or self.config_type == 'int':
         return int(value)
      elif self.config_type == 'long':
         return long(value)
      elif self.config_type == 'double':
         return float(value)
      elif self.config_type == 'string':
         return value
      # TODO: Handle datetime and base64Binary more intelligently.
      elif self.config_type == 'datetime':
         return value
      elif self.config_type == 'base64Binary':
         return value

   def set_cdata(self, value):
      self.__setcdata(str(value))
